package com.learn.quartz.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.learn.quartz.entity.TaskConfigEntity;
import com.learn.quartz.mapper.TaskConfigMapper;
import com.learn.quartz.service.ScheduleJobService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * quartz功能的实现
 *
 * @author: MI
 * @email: 448341911@qq.com
 * @createDate: 2023/10/28 20:10
 * @updateUser: MI
 * @updateDate: 2023/10/28 20:10
 * @updateRemark: 修改内容
 * @version: v1.0
 */
@Slf4j
@Service
public class ScheduleJobServiceImpl extends ServiceImpl<TaskConfigMapper, TaskConfigEntity> implements ScheduleJobService {

    @Resource
    private Scheduler scheduler;

    @Resource
    private TaskConfigMapper taskConfigMapper;


    /**
     * 组装JobDetail
     *
     * @param configEntity
     * @return
     * @throws ClassNotFoundException
     */
    private JobDetail getJobDetail(TaskConfigEntity configEntity) throws ClassNotFoundException {

        Class<? extends Job> aClass = Class.forName(configEntity.getClassName()).asSubclass(Job.class);

        return JobBuilder.newJob()
                .withIdentity(JobKey.jobKey(configEntity.getTaskId()))
                .withDescription(configEntity.getDescription())
                .ofType(aClass).build();
    }

    /**
     * 组装CronTrigger
     *
     * @param configEntity
     * @return
     */
    private CronTrigger getCronTrigger(TaskConfigEntity configEntity) {
        CronTrigger cronTrigger = null;
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(configEntity.getCron());
        cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(TriggerKey.triggerKey(configEntity.getTaskId()))
                .withSchedule(cronScheduleBuilder)
                .build();
        return cronTrigger;
    }

    @Override
    public void startJob() {
        List<TaskConfigEntity> taskConfigEntities = taskConfigMapper.selectList(
                Wrappers.<TaskConfigEntity>lambdaQuery()
                        .eq(TaskConfigEntity::getStatus, 1));
        if (taskConfigEntities == null || taskConfigEntities.size() == 0) {
            log.error("定时任务加载数据为空!");
            return;
        }
        for (TaskConfigEntity configEntity : taskConfigEntities) {
            CronTrigger cronTrigger = null;
            JobDetail jobDetail = null;
            try {
                cronTrigger = getCronTrigger(configEntity);
                jobDetail = getJobDetail(configEntity);
                scheduler.scheduleJob(jobDetail, cronTrigger);
                log.info("编号：{}定时任务加载成功!", configEntity.getTaskId());
            } catch (Exception e) {
                log.error("编号：{}定时任务加载失败!", configEntity.getTaskId());
            }

        }
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            log.error("定时任务启动失败", e);
        }

    }

    @Override
    public void stopJob(String taskId) throws SchedulerException {
        scheduler.pauseJob(JobKey.jobKey(taskId));
    }

    @Override
    public void resumeJob(String taskId) throws SchedulerException {
        scheduler.resumeJob(JobKey.jobKey(taskId));
    }

    @Override
    public void loadJob(String taskId) throws SchedulerConfigException {
        TaskConfigEntity taskConfigEntity = taskConfigMapper.selectOne(Wrappers.<TaskConfigEntity>lambdaQuery()
                .eq(TaskConfigEntity::getTaskId, taskId)
                .eq(TaskConfigEntity::getStatus, 1));
        if (null == taskConfigEntity) {
            throw new SchedulerConfigException("未找到相关Job配置");
        }
        try {
            JobDetail jobDetail = getJobDetail(taskConfigEntity);
            CronTrigger cronTrigger = getCronTrigger(taskConfigEntity);
            scheduler.scheduleJob(jobDetail, cronTrigger);
        } catch (Exception e) {
            log.error("加载定时任务异常", e);
            throw new SchedulerConfigException("加载定时任务异常", e);
        }
    }

    @Override
    public void unloadJob(String taskId) throws SchedulerException {
        // 停止触发器
        scheduler.pauseTrigger(TriggerKey.triggerKey(taskId));
        // 卸载定时任务
        scheduler.unscheduleJob(TriggerKey.triggerKey(taskId));
        // 删除原来的job
        scheduler.deleteJob(JobKey.jobKey(taskId));
    }

    @Override
    public void reload(String taskId) throws Exception {
        TaskConfigEntity taskConfigEntity = taskConfigMapper.selectOne(
                Wrappers.<TaskConfigEntity>lambdaQuery()
                        .eq(TaskConfigEntity::getTaskId, taskId)
                        .eq(TaskConfigEntity::getStatus, 1));
        String jobCode = taskConfigEntity.getTaskId();
        // 获得以前的触发器
        TriggerKey triggerKey = TriggerKey.triggerKey(jobCode);
        // 停止触发器
        scheduler.pauseTrigger(triggerKey);
        // 删除触发器
        scheduler.unscheduleJob(triggerKey);
        // 删除原来的job
        scheduler.deleteJob(JobKey.jobKey(jobCode));
        JobDetail jobDetail = getJobDetail(taskConfigEntity);
        CronTrigger cronTrigger = getCronTrigger(taskConfigEntity);
        // 重新加载job
        scheduler.scheduleJob(jobDetail, cronTrigger);
    }
}
